package dswitch2;

import com.derbysoft.lowcostadapter.commons.utils.DateTimeUtils;
import com.derbysoft.lowcostadapter.dswitch2.service.helper.Constant;
import com.derbysoft.remote.dswitch.core.*;
import com.derbysoft.remote.dswitch.generic.constants.AgeQualifyingType;
import com.derbysoft.remote.dswitch.generic.constants.UniqueIDType;
import com.derbysoft.remote.dswitch.generic.dto.UniqueIDDTO;
import com.derbysoft.remote.dswitch.hotel.adapter.hotelprovider.HotelProviderWebService;
import com.derbysoft.remote.dswitch.hotel.adapter.hotelprovider.httpinvoker.HttpInvokerHotelProviderWebServiceFactory;
import com.derbysoft.remote.dswitch.hotel.dto.*;
import com.derbysoft.remote.share.LanguageType;
import com.derbysoft.remote.share.dto.TPAExtensionsDTO;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by: jason
 * Date: 2012-08-06
 */
public class GetAvailTask implements Runnable {
    private static final String URL = "http://175.41.213.105/dswitch2-lowcost-adapter/";
    //private static final String URL = "http://10.200.107.35/dswitch2-lowcost-adapter/";
    private static final String SOURCE = "AA72317001A40BD0E11BAAFF85B632B168BA";
    protected static final String HOTEL_PASSPORT = "AA72317001A40BD0E11BAAFF85B632B168BA";
    protected static final String TASK_ID = "TaskId";
    protected static final String CHECKIN_DATE = "2012-08-25";
    protected static final int NUMBER_OF_UNITS = 1;
    protected static final int DURATION = 2;
    protected static final int ADULTS = 1;
    protected static final int CHILDREN = 0;

    static HttpInvokerHotelProviderWebServiceFactory factory =
            new HttpInvokerHotelProviderWebServiceFactory(URL);
    static HotelProviderWebService hotelProviderWebService = factory.getHotelProviderWebService();

    @Override
    public void run() {
        getAvail();
    }

    private void getAvail() {

        GenericRQ<HotelAvailRQ> rq = createRQ();
        GenericRS<HotelAvailRS> rs = hotelProviderWebService.getAvailability(rq);
        for (AvailRoomStayDTO availRoomStayDTO : rs.getPayload().getHotelAvailRoomStay().getRoomStays()) {
            String log = String.format("RatePlan: %s[%s] RoomType: %s[%s]", availRoomStayDTO.getRatePlan().getName(),
                    availRoomStayDTO.getRatePlan().getCode(),
                    availRoomStayDTO.getRoomType().getName(),
                    availRoomStayDTO.getRoomType().getCode());
            System.out.println(log);
        }
        //System.out.println("ID:" + Thread.currentThread().getId() + ", Name:" + Thread.currentThread().getName());
    }

    private GenericRQ<HotelAvailRQ> createRQ() {
        return new GenericRQ<HotelAvailRQ>(createHeader(), createPayload());
    }

    private HotelAvailRQ createPayload() {
        HotelAvailRQ hotelAvailRQ = new HotelAvailRQ();
        hotelAvailRQ.setAvailCriteria(createAvailCriteria());
        TPAExtensionsDTO tpaExtensions = new TPAExtensionsDTO();
        tpaExtensions.setElement(Constant.DISALLOW_FROM_CACHE, Boolean.TRUE.toString());
//        hotelAvailRQ.setTpaExtensions(tpaExtensions);
        return hotelAvailRQ;
    }

    private HotelAvailCriteriaDTO createAvailCriteria() {
        HotelAvailCriteriaDTO hotelAvailCriteriaDTO = new HotelAvailCriteriaDTO();
        hotelAvailCriteriaDTO.setHotelRef(createHotelRef());
        hotelAvailCriteriaDTO.setStayDateRange(createStayDateRange());
        hotelAvailCriteriaDTO.setRoomStayCandidates(createRoomStayCandidates());
        hotelAvailCriteriaDTO.setLanguageType(LanguageType.EN_US);
        return hotelAvailCriteriaDTO;
    }

    private RoomStayCandidateDTO createRoomStayCandidates() {
        RoomStayCandidateDTO roomStayCandidateDTO = new RoomStayCandidateDTO();
        roomStayCandidateDTO.setGuestCounts(createGuestCounts());
        roomStayCandidateDTO.setNumberOfUnits(NUMBER_OF_UNITS);
        return roomStayCandidateDTO;
    }

    protected HotelRefDTO createHotelRef() {
        HotelRefDTO hotelRefDTO = new HotelRefDTO();
        hotelRefDTO.setCode(HOTEL_PASSPORT);
        return hotelRefDTO;
    }

    protected RequestHeader createHeader() {
        RequestHeader requestHeader = new RequestHeader();
        requestHeader.setTaskId(TASK_ID);
        requestHeader.setSource(createSource());
        requestHeader.setDestinations(createDestinations());
        requestHeader.setProducts(createProducts());
        return requestHeader;
    }

    private List<UniqueIDDTO> createProducts() {
        ArrayList<UniqueIDDTO> products = new ArrayList<UniqueIDDTO>();
        products.add(new UniqueIDDTO(HOTEL_PASSPORT, UniqueIDType.HOTEL));
        return products;
    }

    private List<DestinationDTO> createDestinations() {
        ArrayList<DestinationDTO> destinationDTOs = new ArrayList<DestinationDTO>();
        destinationDTOs.add(createDestination());
        return destinationDTOs;
    }

    private DestinationDTO createDestination() {
        DestinationDTO destinationDTO = new DestinationDTO();
        destinationDTO.setUniqueID(new UniqueIDDTO("LOWCOSTBEDS", UniqueIDType.HOTEL));
        return destinationDTO;
    }

    private SourceDTO createSource() {
        SourceDTO sourceDTO = new SourceDTO();
        sourceDTO.setUniqueID(new UniqueIDDTO(SOURCE, UniqueIDType.TRAVEL_AGENCY));
        return sourceDTO;
    }

    protected List<GuestCountDTO> createGuestCounts() {
        ArrayList<GuestCountDTO> guestCountDTOs = new ArrayList<GuestCountDTO>();
        guestCountDTOs.add(new GuestCountDTO(AgeQualifyingType.ADULT, ADULTS));
        guestCountDTOs.add(new GuestCountDTO(AgeQualifyingType.CHILD, CHILDREN));
        return guestCountDTOs;
    }

    protected StayDateRangeDTO createStayDateRange() {
        StayDateRangeDTO stayDateRangeDTO = new StayDateRangeDTO();
        stayDateRangeDTO.setCheckInDate(DateTimeUtils.parse(CHECKIN_DATE));
        stayDateRangeDTO.setCheckOutDate(DateTimeUtils.offsetDays(stayDateRangeDTO.getCheckInDate(), DURATION));
        return stayDateRangeDTO;
    }
}
